home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Dr. Windows 3
/
dr win3.zip
/
dr win3
/
PROGRAMR
/
OLE2BOOK.ZIP
/
CHAP08.ZIP
/
CHAP08
/
PATRON
/
PAGEMOUS.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1993-06-07
|
16KB
|
661 lines
/*
* PAGEMOUS.CPP
* Modifications for Chapter 8
*
* Implementation of mouse-related member functions of CPage.
* The remainder is in PAGE.CPP. This separate file keeps this
* grungy hit-testing/drawing code out of our way.
*
* Copyright (c)1993 Microsoft Corporation, All Rights Reserved
*
* Kraig Brockschmidt, Software Design Engineer
* Microsoft Systems Developer Relations
*
* Internet : kraigb@microsoft.com
* Compuserve: >INTERNET:kraigb@microsoft.com
*/
#include "patron.h"
//Lookups into the array using g_rgHTCode[x+y*3] in PAGEMOUS.CPP
#define YTOP 0
#define YMID 1
#define YBOT 2
#define XLEFT 0
#define XMID 1
#define XRIGHT 2
//Values to restrict sizing in CPage::OnMouseMove
#define SIZINGTOP 0x0001
#define SIZINGBOTTOM 0x0002
#define SIZINGLEFT 0x0004
#define SIZINGRIGHT 0x0008
//This array is for hit-testing lookups
static UINT g_rgHTCode[9]={HTTOPLEFT, HTTOP, HTTOPRIGHT
, HTLEFT, HTCLIENT, HTRIGHT, HTBOTTOMLEFT, HTBOTTOM, HTBOTTOMRIGHT};
//This is for restricting tracking based on the hit-test
static UINT g_rguSizingFlags[9]={SIZINGTOP | SIZINGLEFT, SIZINGTOP
, SIZINGTOP | SIZINGRIGHT, SIZINGLEFT, 0, SIZINGRIGHT
, SIZINGBOTTOM | SIZINGLEFT, SIZINGBOTTOM, SIZINGBOTTOM | SIZINGRIGHT};
/*
* CPage::OnLeftDown
*
* Purpose:
* Called when the user clicks with the left button on this page.
* We find the object under that position that is visibly on top
* (always the first one under this location in the page list since
* we paint in reverse order) and select it.
*
* Parameters:
* uKeys UINT carrying the key state.
* x, y UINT coordinates of the click in device units.
*
* Return Value:
* BOOL Indicates if the action changed the object.
*/
BOOL CPage::OnLeftDown(UINT uKeys, UINT x, UINT y)
{
UINT iTenant;
LPTENANT pTenant;
RECT rc;
//CHAPTER8MOD
if (HTCAPTION==m_uHTCode)
return DragDrop(uKeys, x, y);
//End CHAPTER8MOD
/*
* See if we have to start sizing (which always happens on current
* tenant). m_uHTCode is set in OnNCHitTest below.
*/
if (HTNOWHERE!=m_uHTCode && HTCLIENT!=m_uHTCode)
{
//We are sizing, so start tracking
m_pTenantCur->RectGet(&m_rcl, TRUE);
SetCapture(m_hWnd);
m_fTracking=TRUE;
m_hDC=GetDC(m_hWnd);
//Place the rectangle exactly where it is on the screen.
RECTFROMRECTL(rc, m_rcl)
OffsetRect(&rc, -(int)m_pPG->m_xPos, -(int)m_pPG->m_yPos);
RECTLFROMRECT(m_rcl, rc);
m_rclOrg=m_rcl;
DrawFocusRect(m_hDC, &rc);
m_pPG->CalcBoundingRect(&rc, TRUE);
RECTLFROMRECT(m_rclBounds, rc);
return FALSE;
}
iTenant=TenantFromPoint(x, y, &pTenant);
if (NULL==pTenant)
return FALSE;
//If this one is already current, we might be now sizing.
if (pTenant==m_pTenantCur)
return FALSE;
//Deselect the current tenant
if (NULL!=m_pTenantCur)
m_pTenantCur->Select(FALSE);
//Move this tenant to the top of the list
m_iTenantCur=0;
SendMessage(m_hWndTenantList, LB_DELETESTRING, iTenant, 0L);
SendMessage(m_hWndTenantList, LB_INSERTSTRING, 0, (LONG)pTenant);
//Select and repaint the new tenant to show it up front
m_pTenantCur=pTenant;
m_pTenantCur->Repaint();
m_pTenantCur->Select(TRUE);
return FALSE;
}
/*
* CPage::OnLeftUp
*
* Purpose:
* Called when the user clicks up with the left button on this page.
* We stop tracking on this message, if necessary, and resize the object.
*
* Parameters:
* uKeys UINT carrying the key state.
* x, y UINT coordinates of the click in device units.
*
* Return Value:
* BOOL Indicates if this action changed the object.
*/
BOOL CPage::OnLeftUp(UINT uKeys, UINT x, UINT y)
{
RECT rc, rcT;
if (!m_fTracking)
return FALSE;
//Remove the dotted rectangle.
RECTFROMRECTL(rc, m_rcl)
DrawFocusRect(m_hDC, &rc);
ReleaseDC(m_hWnd, m_hDC);
ReleaseCapture();
m_fTracking=FALSE;
//If the original and new rects are the same, nothing happened.
RECTFROMRECTL(rcT, m_rclOrg);
if (EqualRect(&rc, &rcT))
return FALSE;
RECTFROMRECTL(rcT, m_rclOrg);
InvalidateRect(m_hWnd, &rcT, TRUE);
//Invalidate on the screen before accounting for scrolling
InvalidateRect(m_hWnd, &rc, TRUE);
//Factor in the scrolling and tell the tenant where it now stands.
OffsetRect(&rc, (int)m_pPG->m_xPos, (int)m_pPG->m_yPos);
RECTLFROMRECT(m_rcl, rc);
m_pTenantCur->RectSet(&m_rcl, TRUE);
UpdateWindow(m_hWnd);
return TRUE;
}
/*
* CPage::OnLeftDoubleClick
*
* Purpose:
* Called when the user double-clicks with the left button on this page.
* We find the object under that position that is visibly on top
* (always the first one under this location in the page list since
* we paint in reverse order) and activate it.
*
* Parameters:
* uKeys UINT carrying the key state.
* x, y UINT coordinates of the click in device units.
*
* Return Value:
* BOOL Indicates if the action changed the object.
*/
BOOL CPage::OnLeftDoubleClick(UINT uKeys, UINT x, UINT y)
{
/*
* The current tenant is the only one that can be activated, so
* we just have to make sure the mouse is there. For that we can
* use the last hit-test code we saw since it's updated on every
* mouse move.
*/
if (HTNOWHERE!=m_uHTCode)
return m_pTenantCur->Activate(OLEIVERB_PRIMARY);
return FALSE;
}
/*
* CPage::OnNCHitTest
*
* Purpose:
* Processes WM_NCHITTEST on a page so we can check for hits on the
* handles of the selected object for resizing. We only save information
* for ourselves and do not interfere with normal hit-testing.
*
* Parameters:
* x, y UINT device coordinates to check.
*
* Return Value:
* None
*/
void CPage::OnNCHitTest(UINT x, UINT y)
{
RECT rc;
RECTL rcl;
int iMid1, iMid2;
int xHit, yHit;
POINT pt;
int x0, y0;
//By default we won't start sizing on a click and don't hit an object.
m_uSizingFlags=0;
m_uHTCode=HTNOWHERE;
if (NULL==m_pTenantCur)
return;
//Convert device points to our coordinates
m_pTenantCur->RectGet(&rcl, FALSE);
RECTFROMRECTL(rc, rcl);
RectConvertMappings(&rc, NULL, TRUE);
OffsetRect(&rc, -(int)m_pPG->m_xPos, -(int)m_pPG->m_yPos);
SETPOINT(pt, x, y);
ScreenToClient(m_hWnd, &pt);
x0=pt.x;
y0=pt.y;
if (x0 < rc.left || x0 > rc.right)
return;
if (y0 < rc.top || y0 > rc.bottom)
return;
//It's at least in the object.
m_uHTCode=HTCLIENT;
//Check for hits in horizontal regions
xHit=-1;
iMid1=rc.left+((rc.right-rc.left-CXYHANDLE) >> 1);
iMid2=rc.left+((rc.right-rc.left+CXYHANDLE) >> 1);
if (x0 >= rc.left && x0 <= rc.left+CXYHANDLE)
xHit=XLEFT;
else if (x0 >= iMid1 && x0 <= iMid2)
xHit=XMID;
else if (x0 >= rc.right-CXYHANDLE && x0 <= rc.right)
xHit=XRIGHT;
//CHAPTER8MOD
//Don't exit yet if we didn't hit a handle--might hit a y edge.
//End CHAPTER8MOD
//Check for hits in vertical regions
yHit=-1;
iMid1=rc.top+((rc.bottom-rc.top-CXYHANDLE) >> 1);
iMid2=rc.top+((rc.bottom-rc.top+CXYHANDLE) >> 1);
if (y0 >= rc.top && y0 <= rc.top+CXYHANDLE)
yHit=YTOP;
else if (y0 >= iMid1 && y0 <= iMid2)
yHit=YMID;
else if (y0 >= rc.bottom-CXYHANDLE && y0 <= rc.bottom)
yHit=YBOT;
//CHAPTER8MOD
/*
* If we hit any edge, but didn't hit a ha